Retrofit 自定义 ConverterFactory 处理 resposne
in Android with 0 comment

Retrofit 自定义 ConverterFactory 处理 resposne

in Android with 0 comment

Retrofit自定义ConverterFactory

有时候我们用Retrofit需要在收到请求后处理response,当然写在RXJava的回调中也是可以的。 但是如果需要处理的耗时比较长UI线程就会卡住,或者需要重复使用这一段处理(例如解密参数)时代码就会很乱。 为了解决这个问题,我们可以自定义一个ConverterFactory 使用方法如下(第4行)

    private static Retrofit mRetrofit = new Retrofit.Builder()
            .baseUrl("https://acharts.co/")
            .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
            .addConverterFactory(RankConverterFactory.create())
            .build();

这个是接口,记住这个泛型List,后面会用到

    @GET("/uk_singles_top_75")
    Observable<List> getUK();

我们需要继承Converter.Factory抽象类,并且按照需求实现它的方法。 比如我们想要处理response,则重写responseBodyConverter方法,让它返回一个Converter(用于处理response的类),也就是说,在Factory中只是判断是否处理,如果处理的话就提供相应的Converter。处理response发生在Coverter中。

我们这里只需要处理response,所以只重写了responseBodyConverter 下面是代码

public class RankConverterFactory extends Converter.Factory {
//工厂方法,用于创建实例
    public static RankConverterFactory create() {
        return new RankConverterFactory();
    }
    
//response返回到本地后会被调用,这里先判断是否要拦截处理,不拦截则返回null
//判断是否处理的依据就是type参数,type就是上面接口出现的List了
    @Override
    public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
        if (type == List.class) {
            return new RankBodyConverter<Type>();
        }
        //如果返回null则不处理,交给别的Converter处理
        return null;

    }
    
// 一个Converter类,T就是上面接口中的List了
    private static class RankBodyConverter<T> implements Converter<ResponseBody, T> {
        RankBodyConverter() {
        }
        //在这个方法中处理response
        @Override
        public T convert(ResponseBody value) throws IOException {
            String body = value.string();
            return (T) ResponseUtil.handleRankResponse(body);

        }
    }
}

可能看到这么多泛型会晕。不要着急,这些泛型用来干什么的呢?让我们理一理 由于一个Retrofit实例可以添加多个ConverterFactory,那么他如何判断是否由这个ConverterFactory处理呢? 答案就是判断通过接口的泛型(上面送List),在responseBodyConverter方法中, 首先判断接口中的泛型是否为List类型,type == List.class 如果是就返回相应的Converter表示处理response,如果不是就返回null交给别的ConverterFactory处理。